先來打造一個很酷的數組
let obj = {
'0': 'a',
'1': 'b',
'2': 'c',
'length': 3,
'push': Array.prototype.push
}
console.log(obj);
乍看之下他還只是一個平常的對象,但其實這個對象這時候已經變成一個類數組了!
我們來對他做以下操作可以更明白
可以發現到這時候他多了一個 3: "d" ,對象原本是不能這樣做的,但是在這邊卻可以實現,因此才對他取名叫做類數組。
要打造出一個類數組有幾個條件
- 他必須要是一個對象
- 屬性要為索引(數字)值
- 一定要有length存在
- 最好可以加push
附註:
如果想讓它變得更像數組可以加上splice,如下圖
let obj = {
'2': 'c',
'3': 'd',
'length': 3,
'push': Array.prototype.push,
};
obj.push('f')
obj.push('g')
console.log(obj);
大家先別看答案,先想想看這個東西打印出來會長怎樣
3的 "d" 居然被 "f" 覆蓋掉了,而且多了一個4 : "g" ,我們來講解一下實現原理!!
擷取自
function ArrayPush () {
var n = TO_UNIT32(this.length); // 被push數組的長度(類數組採用的length就是這個!)
var m = %_ArgumentsLength(); // push的總長度
for (var i = 0; i < m; i++) {
this[i + n ] = %_Arguments(i); // 複製給原數組
}
this.length = n + m; // 修正最終數組長度
return this.length;
}
從第2行可以得知為甚麼Obj一定要有length
再來第4到6行就能知道他push的觀點全是在length上
也就是說在obj對象最該觀察的不是其他元素而是length!
let obj = {
'2': 'c',
'3': 'd',
'length': 3,
'push': Array.prototype.push,
};
obj.push('f')
obj.push('g')
console.log(obj);
到這邊就很明瞭為甚麼 3會變f 而 4會變g,原因全在
大家可以想一下i = 0 的情況下會發生甚麼事,是不是this[0 + n]會被push的第一個元素取代,那這裡他的n代表的不就是Obj的 length
就表示說Obj [3] 會被 f 取代,並且length變4 ,然後Obj[4]再被 g取代,length變5!這就是這題的實現原理。